using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;

using GarageGames.Torque.Core;
using GarageGames.Torque.Util;
using GarageGames.Torque.Sim;
using GarageGames.Torque.T3D;
using GarageGames.Torque.SceneGraph;
using GarageGames.Torque.MathUtil;
using GarageGames.Torque.Materials;

namespace TimeWar
{
    [TorqueXmlSchemaType]
    public class ParticleEffects : TorqueComponent, ITickObject
    {
        //======================================================
        #region Static methods, fields, constructors
        #endregion

        //======================================================
        #region Constructors
        #endregion

        //======================================================
        #region Public properties, operators, constants, and enums

        #endregion

        //======================================================
        #region Public methods

        public virtual void ProcessTick(Move move, float dt)
        {
            // todo: perform processing for component here
        }

        public virtual void InterpolateTick(float k)
        {
            // todo: interpolate between ticks as needed here
        }

        public override void CopyTo(TorqueComponent obj)
        {
            base.CopyTo(obj);
        }

        public static void Explosion(Vector3 position)
        {
            //create a scene object to hold the particle effect
            TorqueObject objParticleEffect = new TorqueObject();
            SimpleMaterial particleMaterial = new SimpleMaterial();
            particleMaterial.Name = "SparkleParticleMaterial";
            particleMaterial.TextureFilename = "data/Particles/Flame02.png";
            particleMaterial.IsTranslucent = true;
            particleMaterial.IsColorBlended = true;

            //setup the particle data
            T3DParticleData particleData = new T3DParticleData();
            particleData.Material = particleMaterial;
            particleData.UseInvAlpha = false;
            particleData.DragCoefficient = 0;
            particleData.GravityCoefficient = -0.05f;
            particleData.WindCoefficient = 0.5f;
            particleData.SpinRandomMin = -30.0f;
            particleData.SpinRandomMax = 30.0f;
            particleData.LifeTimeMS = 4000;
            particleData.LifeTimeVarianceMS = 250;
            particleData.Times = new float[3] { 0.0f, 0.5f, 1.0f };
            particleData.Sizes = new float[3] { 0.5f, 0.75f, 1.5f };
            particleData.Colors = new Vector4[] {
new Vector4(0.9f, 0.9f, 0.9f, 0.2f),
new Vector4(0.9f, 0.9f, 0.9f, 0.9f),
new Vector4(0.9f, 0.9f, 0.9f, 0.0f) };

            //setup the emitter data
            T3DParticleEmitterData emitterData = new T3DParticleEmitterData();
            emitterData.EjectionPeriodMS = 25;
            emitterData.EjectionVelocity = 0.5f;
            emitterData.VelocityVariance = 0.5f;
            emitterData.EjectionOffset = 0;
            emitterData.ThetaMin = 0;
            emitterData.ThetaMax = 90;
            emitterData.OrientParticles = true;
            emitterData.ParticleData = particleData;

            //setup the emitter
            T3DParticleEmitter emitter = new T3DParticleEmitter();
            emitter.UseLocalTransform = true;
            emitter.ParticleEmitterData = emitterData;

            //setup the particle effect
            T3DParticleEffectComponent componentEffect = new T3DParticleEffectComponent();
            componentEffect.SceneGroupName = "ParticleEffectObject";
            componentEffect.PlayOnRegister = true;
            componentEffect.DeleteWhenFinished = false;
            componentEffect.Emitters.Add(emitter);
            objParticleEffect.Components.AddComponent(componentEffect);
            T3DSceneComponent componentScene = new T3DSceneComponent();
            componentScene.SceneGroup = "ParticleEffectObject";
            componentScene.Position = position;
            objParticleEffect.Components.AddComponent(componentScene);

            //register the particle emitter
            TorqueObjectDatabase.Instance.Register(objParticleEffect);
            return;
        }


        #endregion

        //======================================================
        #region Private, protected, internal methods

        protected override bool _OnRegister(TorqueObject owner)
        {
            if (!base._OnRegister(owner))
                return false;

            // todo: perform initialization for the component

            // todo: look up interfaces exposed by other components
            // E.g., 
            // _theirInterface = Owner.Components.GetInterface<ValueInterface<float>>("float", "their interface name");            

            return true;
        }

        protected override void _OnUnregister()
        {
            // todo: perform de-initialization for the component

            base._OnUnregister();
        }

        protected override void _RegisterInterfaces(TorqueObject owner)
        {
            base._RegisterInterfaces(owner);

            // todo: register interfaces to be accessed by other components
            // E.g.,
            // Owner.RegisterCachedInterface("float", "interface name", this, _ourInterface);
        }


        #endregion

        //======================================================
        #region Private, protected, internal fields
        #endregion
    }
}
